﻿unit global;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, uLkJSON, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP, PerlRegEx, Buttons,
  IdIOHandler, IdIOHandlerSocket, IdSSLOpenSSL, IdIOHandlerStack, IdSSL,IdURI,
  OleCtrls, SHDocVw,Generics.Collections;

const
   XorKey:array[0..7] of Byte=($B2,$09,$AA,$55,$93,$6D,$84,$47); //字符串加密用

function getAreaByMobile(mobileStr:string) : string;
function  json2map(jsonstr:string):TDictionary<string,string>;
function encstr(Str:String):String;
function decstr(Str:String):String;
function includechinese(str:string):Boolean;
function includeerrortxt(str:string):boolean;

implementation

function includechinese(str:string):Boolean;  //判断字符串内是否包含汉字
var
  i : integer;
  ret : boolean;
begin
  ret := False;
  for i := 1 to Length(str) do
  begin
    if (Ord(str[i])>=19968) and (Ord(str[i])<=40869) then
    begin
      ret := True;
      break;
    end;
  end;
  Result := ret;
end;

function includeerrortxt(str:string):boolean; //判断字符串里面可能有错误字符的
var
  i : integer;
  ret : boolean;
begin
  ret := False;
  for i := 1 to Length(str) do
  begin
    if (Ord(str[i])<33) or ((Ord(str[i])>126) and (Ord(str[i])<19968)) or (Ord(str[i])>40869) or (Ord(str[i])<>32) then
    begin
      ret := True;
      break;
    end;
  end;
  Result := ret;
end;



function encstr(Str:String):String;//字符加密函數  這是用的一個異或加密
var
 i,j:Integer;
begin
 Result:='';
 j:=0;
 for i:=1 to Length(Str) do
   begin
     Result:=Result+IntToHex(Byte(Str[i]) xor XorKey[j],2);
     j:=(j+1) mod 8;
   end;
end;

function decstr(Str:String):String;//字符解密函數
var
 i,j:Integer;
begin
 Result:='';
 j:=0;
 for i:=1 to Length(Str) div 2 do
   begin
     Result:=Result+Char(StrToInt('$'+Copy(Str,i*2-1,2)) xor XorKey[j]);
     j:=(j+1) mod 8;
   end;
end;

function getAreaByMobile(mobileStr:string) : string;
var
  Response:TStringStream;
  pageStr: String;
  reg: TPerlRegEx;
  str1,str2,citystr,areastr,zipstr: String;
  pos1,pos2 : Integer;
  strlist : TStringList;
  idhtp1 : TIdHTTP;
begin
  idhtp1 := TIdHTTP.Create(nil);
  idhtp1.HandleRedirects:= true;
  idhtp1.ReadTimeout:= 30000;
  idhtp1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
	Response := TStringStream.Create('');
  try
    idhtp1.get('http://www.youdao.com/smartresult-xml/search.s?type=mobile&q='+mobileStr,Response);
    pageStr:= Response.DataString;
    reg := TPerlRegEx.Create;
    reg.Subject := pageStr;
    reg.RegEx   := '<location>'+'[\s\S]*?'+'</location>';
    if reg.MatchAgain then
    begin
        str2 := reg.MatchedText;
        Str2 := StringReplace (Str2, '<location>', '', [rfReplaceAll]);
        Str2 := StringReplace (Str2, '</location>', '', [rfReplaceAll]);
    end;
    FreeAndNil(reg);
    Result := Str2;
  except
    Result := '';
  end;
  idhtp1.Free;
end;

function  json2map(jsonstr:string):TDictionary<string,string>;
var
  js:TlkJSONobject;
  datalist: TlkJSONlist;
  dataobj: TlkJSONobject;
  keystr : string;
  i,j: Integer;
  keyval,typeval,tmpstr : string;
  contact_id,group_id,username,cardsource,cardstate,cloudcheck,sync_cid,timecreate : String;
  mobile,tel,fax,email,website,qq : String;
  country,state,city,street1,street2,zip : String;
  company,department,title : String;
  front_pic_url,front_pic_angle,front_pic_value,back_pic_url,back_pic_angle,back_pic_value : String;
  reg: TPerlRegEx;
  FHT:TDictionary<string,string>;
  retlist : Tstringlist;
  ischinese : Boolean;
  addr_arr,comp_arr,addtmp,comptmp : array of array of string;
  len1 : Integer;
  ocrtext : String;
begin
  js := TlkJSON.ParseText(jsonstr) as TlkJSONobject;
  if (js.Field['data'].SelfType = jsList) then
  begin
    datalist := js.Field['data'] as TlkJSONlist;
    for i:=0 to datalist.Count-1 do
    begin
      dataobj := datalist.Child[i] as TlkJSONobject;
      keyval := VarToStr(dataobj.Field['key'].Value);
      if  keyval='contact_id' then
        begin
          contact_id := dataobj.Field['contact_id'].Value;
          group_id := VarToStr(dataobj.Field['group_id'].Value);
          cardsource := VarToStr(dataobj.Field['cardsource'].Value);
          cardstate := VarToStr(dataobj.Field['cardstate'].Value);
          cloudcheck := VarToStr(dataobj.Field['cloudcheck'].Value);
          sync_cid := VarToStr(dataobj.Field['sync_cid'].Value);
          timecreate := VarToStr(dataobj.Field['timecreate'].Value);
        end
      else if keyval='name' then
        begin
          username := VarToStr(dataobj.Field['username'].Value);
          username := stringreplace(username,' ','',[rfReplaceAll]);
        end
      else if keyval='phone' then
        begin
          typeval := VarToStr(dataobj.Field['type'].Value);
          if typeval='CELL' then  mobile := mobile + ' ' + VarToStr(dataobj.Field['value'].Value)
          else if typeval='WORK;FAX' then fax := fax + ' ' + VarToStr(dataobj.Field['value'].Value)
          else if typeval='WORK' then  tel := tel + ' ' + VarToStr(dataobj.Field['value'].Value);
        end
      else if keyval='email' then
        begin
          email := email + ' ' + VarToStr(dataobj.Field['value'].Value);
        end
      else if keyval='website' then
        begin
          website := website + ' ' + VarToStr(dataobj.Field['value'].Value);
        end
      else if keyval='im' then
        begin
          typeval := VarToStr(dataobj.Field['type'].Value);
          if pos('QQ',typeval)>0 then  qq := qq + ' ' + VarToStr(dataobj.Field['value'].Value)
        end
      else if keyval='address' then
          begin
          {
            reg := TPerlRegEx.Create;
            reg.Subject := VarToStr(dataobj.Field['street1'].value);
            reg.RegEx := '[\x80-\xff]+';
            if reg.MatchAgain then
            begin
            }
              len1 := Length(addr_arr)+1;
              SetLength(addr_arr,len1,6);
              //取国家/省/市/地址/邮编
              //showmessage(dataobj.Field['street1'].value);
              //showmessage(WideCharLenToString(dataobj.Field['street1'].value));
              addr_arr[len1-1,0] := VarToStr(dataobj.Field['street1'].value);
              if dataobj.Field['street2']=nil then
                addr_arr[len1-1,1] := ''
              else
                addr_arr[len1-1,1] :=  VarToStr(dataobj.Field['street2'].Value);
              addr_arr[len1-1,2] :=  VarToStr(dataobj.Field['city'].Value);
              addr_arr[len1-1,3] :=  VarToStr(dataobj.Field['country'].Value);
              addr_arr[len1-1,4] :=  VarToStr(dataobj.Field['state'].Value);
              addr_arr[len1-1,5] :=  VarToStr(dataobj.Field['zip'].Value);
            {end;
            reg.Free; }
          end
      else if keyval='company' then
          begin
            {reg := TPerlRegEx.Create;
            reg.Subject := VarToStr(dataobj.Field['company'].value);
            reg.RegEx := '[\x80-\xff]+';
            if reg.MatchAgain then
            begin }
              len1 := Length(comp_arr)+1;
              SetLength(comp_arr,len1,3);
              comp_arr[len1-1,0] := VarToStr(dataobj.Field['company'].Value);
              if dataobj.Field['department']=nil then
                comp_arr[len1-1,1] := ''
              else
                comp_arr[len1-1,1] := VarToStr(dataobj.Field['department'].Value);
              if dataobj.Field['title']=nil then
                comp_arr[len1-1,2] := ''
              else
                comp_arr[len1-1,2] := VarToStr(dataobj.Field['title'].Value);
            {end;
            reg.Free;}
          end
      else if keyval='front_pic' then
          begin
           front_pic_url  := VarToStr(dataobj.Field['url'].Value);
           if dataobj.Field['angle']=nil then
            front_pic_angle := ''
           else
             front_pic_angle := VarToStr(dataobj.Field['angle'].Value);
           front_pic_value := VarToStr(dataobj.Field['value'].Value);
          end
      else if keyval='back_pic' then
          begin
            back_pic_url  := VarToStr(dataobj.Field['url'].Value);
            back_pic_angle := VarToStr(dataobj.Field['angle'].Value);
            back_pic_value := VarToStr(dataobj.Field['value'].Value);
          end;
    end;
  end;

  js.Free;

  reg := TPerlRegEx.Create;
  ischinese := false;

  //将获取的原始资料存储
  {
  //判断改名片是否是中文名片,username,street1,company
  reg.Subject := username;
  reg.RegEx := '[\x80-\xff]+';
  if reg.MatchAgain then
    ischinese := true;
  for i:=0 to length(comp_arr)-1 do
  begin
    reg.Subject := comp_arr[i,0];
    if reg.MatchAgain then
      ischinese := True;
  end;
  for i:=0 to length(addr_arr)-1 do
  begin
    reg.Subject := addr_arr[i,0];
    if reg.MatchAgain then
      ischinese := True;
  end;
  }
  if includechinese(username) then
    ischinese := true;
  if not ischinese then
    for i:=0 to length(comp_arr)-1 do
    begin
      if includechinese(comp_arr[i,0]) then
      begin
        ischinese := True;
        Break;
      end;
    end;
  if not ischinese then
    for i:=0 to length(addr_arr)-1 do
    begin
      if includechinese(addr_arr[i,0]) then
      begin
        ischinese := True;
        Break;
      end;
    end;

  //如果是中文名片，去掉address和company里面的英文
  if ischinese then
  begin
    for i:=0 to length(comp_arr)-1 do
    begin
      //reg.Subject := comp_arr[i,0]+comp_arr[i,1]+comp_arr[i,2];
      //if reg.MatchAgain then
      if includechinese(comp_arr[i,0]) then
      begin
        len1 := Length(comptmp)+1;
        SetLength(comptmp,len1,3);
        comptmp[len1-1,0] := comp_arr[i,0];
        comptmp[len1-1,0] := stringreplace(comptmp[len1-1,0],' ','',[rfReplaceAll]);
        comptmp[len1-1,1] := comp_arr[i,1];
        comptmp[len1-1,2] := comp_arr[i,2];
      end;
    end;
    for i:=0 to length(addr_arr)-1 do
    begin
      //reg.Subject := addr_arr[i,0]+addr_arr[i,1]+addr_arr[i,2]+addr_arr[i,3]+addr_arr[i,4]+addr_arr[i,5];
      //if reg.MatchAgain then
      if includechinese(addr_arr[i,0]) then
      begin
        len1 := Length(addtmp)+1;
        SetLength(addtmp,len1,6);
        addtmp[len1-1,0] := addr_arr[i,0];
        addtmp[len1-1,0] := stringreplace(addtmp[len1-1,0],' ','',[rfReplaceAll]);
        addtmp[len1-1,1] := addr_arr[i,1];
        addtmp[len1-1,2] := addr_arr[i,2];
        addtmp[len1-1,3] := addr_arr[i,3];
        addtmp[len1-1,4] := addr_arr[i,4];
        addtmp[len1-1,5] := addr_arr[i,5];
      end;
    end;
  end
  else
  begin
    comptmp := comp_arr;
    addtmp := addr_arr;
  end;

  for i:=0 to length(addtmp)-1 do
  begin
    if street1='' then
      street1 := addtmp[i,0]
    else
      street1 := street1+#13#10+addtmp[i,0];
    if street2='' then
      street2 := addtmp[i,1]
    else
      street2 := street2+#13#10+addtmp[i,1];
    if city='' then
      city := addtmp[i,2];
    if country='' then
      country := addtmp[i,3];
    if state='' then
      state := addtmp[i,4];
    if zip='' then
      zip := addtmp[i,5]
    else
      zip := zip+' '+addtmp[i,5];
  end;

  for i:=0 to length(comptmp)-1 do
  begin
    if company='' then
      company := comptmp[i,0]
    else
      company := company+#13#10+comptmp[i,0];
    if department='' then
      department := comptmp[i,1]
    else
      department := department+#13#10+comptmp[i,1];
    if title='' then
      title := comptmp[i,2]
    else
      title := title+#13#10+comptmp[i,2];
  end;


  //正则表达式找tel里面有无手机
  reg.Subject := tel;
  reg.RegEx   := '1[0-9]{10}';
  if reg.MatchAgain then
  begin
    tmpstr := reg.MatchedText;
    if mobile='' then
      mobile := tmpstr
    else
      mobile := ' ' + tmpstr;
    tel := StringReplace(tel,tmpstr,'',[rfReplaceAll]);
  end;
  //手机去掉+86
  mobile := StringReplace(mobile,'+86','',[rfReplaceAll]);
  //根据mobile或者zip,获取省/市
  reg.Subject := mobile;
  reg.RegEx   := '1[0-9]{10}';
  if reg.MatchAgain then
  begin
    tmpstr := reg.MatchedText;
    tmpstr := getAreaByMobile(tmpstr);
    city := tmpstr;
  end;
  //公司名称 地址 姓名 职务 部门 里面有没有汉字英文数字以外的，如果有，该记录标记为识别内容有误
  //汉字的unicode编码范围$4E00-$9FA5,十进制范围19968-40869,英文数字字母大小写含符号 33-126

  reg.RegEx := '[^a-zA-Z0-9\_\x80-\xff]';
  //ocrtext
  if username<>'' then ocrtext := '姓名:'+username;
  if mobile<>'' then ocrtext := ocrtext+#13#10+'手机:'+mobile;
  if tel<>'' then ocrtext := ocrtext+#13#10+'电话:'+tel;
  if fax<>'' then ocrtext := ocrtext+#13#10+'传真:'+fax;
  if email<>'' then ocrtext := ocrtext+#13#10+'email:'+email;
  if website<>'' then ocrtext := ocrtext+#13#10+'网址:'+website;
  if qq<>'' then ocrtext := ocrtext+#13#10+'qq:'+qq;
  if country<>'' then ocrtext := ocrtext+#13#10+'国家地区:'+country;
  if state<>'' then ocrtext := ocrtext+#13#10+'省州:'+state;
  if city<>'' then ocrtext := ocrtext+#13#10+'市:'+city;
  if street1<>'' then ocrtext := ocrtext+#13#10+'地址:'+street1;
  if zip<>'' then ocrtext := ocrtext+#13#10+'邮编:'+zip;
  if company<>'' then ocrtext := ocrtext+#13#10+'公司名称:'+company;
  if department<>'' then ocrtext := ocrtext+#13#10+'部门:'+department;
  if title<>'' then ocrtext := ocrtext+#13#10+'职务:'+title;

  reg.Free;

  FHT:=TDictionary<string,string>.Create;
  FHT.Add('contact_id',contact_id);
  FHT.Add('group_id',group_id);
  FHT.Add('cardsource',cardsource);
  FHT.Add('cardstate',cardstate);
  FHT.Add('cloudcheck',cloudcheck);
  FHT.Add('sync_cid',sync_cid);
  FHT.Add('timecreate',timecreate);
  FHT.Add('username',username);
  FHT.Add('mobile',mobile);
  FHT.Add('tel',tel);
  FHT.Add('fax',fax);
  FHT.Add('email',email);
  FHT.Add('website',website);
  FHT.Add('qq',qq);
  FHT.Add('country',country);
  FHT.Add('state',state);
  FHT.Add('city',city);
  FHT.Add('street1',street1);
  FHT.Add('street2',street2);
  FHT.Add('zip',zip);
  FHT.Add('company',company);
  FHT.Add('department',department);
  FHT.Add('title',title);
  FHT.Add('front_pic_url',front_pic_url);
  FHT.Add('front_pic_angle',front_pic_angle);
  FHT.Add('front_pic_value',front_pic_value);
  FHT.Add('back_pic_url',back_pic_url);
  FHT.Add('back_pic_angle',back_pic_angle);
  FHT.Add('back_pic_value',back_pic_value);
  FHT.Add('jsonstr',jsonstr);
  FHT.Add('ocrtext',ocrtext);
  Result := FHT;
end;

end.
